package com.smartscreen.authmanage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.smartscreen.authmanage.dto.LoginRequest;
import com.smartscreen.authmanage.dto.LoginResponse;
import com.smartscreen.authmanage.dto.RefreshTokenRequest;
import com.smartscreen.authmanage.dto.RegisterRequest;
import com.smartscreen.authmanage.entity.User;
import com.smartscreen.authmanage.mapper.UserMapper;
import com.smartscreen.authmanage.service.AuthService;
import com.smartscreen.common.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class AuthServiceImpl implements AuthService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private JwtUtil jwtUtil;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    
    @Override
    public LoginResponse login(LoginRequest loginRequest) {
        // 查询用户
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", loginRequest.getUsername())
                   .eq("status", "ACTIVE");
        User user = userMapper.selectOne(queryWrapper);
        
        if (user == null) {
            throw new RuntimeException("用户不存在或已被禁用");
        }
        
        // 验证密码
        if (!passwordEncoder.matches(loginRequest.getPassword(), user.getPassword())) {
            throw new RuntimeException("用户名或密码错误");
        }
        
        // 生成token - 修正参数顺序
        String accessToken = jwtUtil.generateAccessToken(user.getUsername(), user.getUserId(), user.getUserType());
        String refreshToken = jwtUtil.generateRefreshToken(user.getUsername(), user.getUserId());
        
        // 将refresh token存储到Redis
        String refreshTokenKey = "refresh_token:" + user.getUserId();
        redisTemplate.opsForValue().set(refreshTokenKey, refreshToken, 7, TimeUnit.DAYS);
        
        // 更新最后登录时间
        user.setLastLoginTime(LocalDateTime.now());
        userMapper.updateById(user);
        
        return new LoginResponse(accessToken, refreshToken, user.getUserType(), user.getRealName(), 86400000L);
    }
    
    @Override
    public Boolean validateToken(String token) {
        try {
            String username = jwtUtil.getUsernameFromToken(token);
            if (username == null) {
                return false;
            }
            
            // 检查用户是否存在且状态正常
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("username", username).eq("status", "ACTIVE");
            User user = userMapper.selectOne(queryWrapper);
            
            return user != null && jwtUtil.validateToken(token, username);
        } catch (Exception e) {
            return false;
        }
    }
    
    @Override
    public LoginResponse refreshToken(RefreshTokenRequest refreshTokenRequest) {
        String refreshToken = refreshTokenRequest.getRefreshToken();
        
        // 验证refresh token格式
        if (!jwtUtil.isRefreshToken(refreshToken) || jwtUtil.isTokenExpired(refreshToken)) {
            throw new RuntimeException("无效的刷新令牌");
        }
        
        String userId = jwtUtil.getUserIdFromToken(refreshToken);
        String username = jwtUtil.getUsernameFromToken(refreshToken);
        
        // 验证Redis中的refresh token
        String refreshTokenKey = "refresh_token:" + userId;
        String storedRefreshToken = (String) redisTemplate.opsForValue().get(refreshTokenKey);
        
        if (!refreshToken.equals(storedRefreshToken)) {
            throw new RuntimeException("刷新令牌已失效");
        }
        
        // 查询用户信息
        User user = userMapper.selectById(userId);
        if (user == null || !"ACTIVE".equals(user.getStatus())) {
            throw new RuntimeException("用户不存在或已被禁用");
        }
        
        // 生成新的token - 修正参数顺序
        String newAccessToken = jwtUtil.generateAccessToken(user.getUsername(), user.getUserId(), user.getUserType());
        String newRefreshToken = jwtUtil.generateRefreshToken(user.getUsername(), user.getUserId());
        
        // 更新Redis中的refresh token
        redisTemplate.opsForValue().set(refreshTokenKey, newRefreshToken, 7, TimeUnit.DAYS);
        
        return new LoginResponse(newAccessToken, newRefreshToken, user.getUserType(), user.getRealName(), 86400000L);
    }
    
    @Override
    public User getCurrentUser(String token) {
        String userId = jwtUtil.getUserIdFromToken(token);
        if (userId == null) {
            return null;
        }
        return userMapper.selectById(userId);
    }
    
    @Override
    public LoginResponse register(RegisterRequest registerRequest) {
        // 验证用户名是否已存在
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", registerRequest.getUsername());
        User existingUser = userMapper.selectOne(queryWrapper);
        
        if (existingUser != null) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 验证用户类型
        String userType = registerRequest.getUserType();
        if (!"TEACHER".equals(userType) && !"STUDENT".equals(userType) && !"ADMIN".equals(userType)) {
            throw new RuntimeException("无效的用户类型");
        }
        
        // 验证必填字段
        if (registerRequest.getUsername() == null || registerRequest.getUsername().trim().isEmpty()) {
            throw new RuntimeException("用户名不能为空");
        }
        if (registerRequest.getPassword() == null || registerRequest.getPassword().length() < 6) {
            throw new RuntimeException("密码长度不能少于6位");
        }
        if (registerRequest.getRealName() == null || registerRequest.getRealName().trim().isEmpty()) {
            throw new RuntimeException("真实姓名不能为空");
        }
        
        // 创建新用户
        User newUser = new User();
        newUser.setUserId(UUID.randomUUID().toString());
        newUser.setUsername(registerRequest.getUsername().trim());
        newUser.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
        newUser.setUserType(userType);
        newUser.setRealName(registerRequest.getRealName().trim());
        newUser.setStatus("ACTIVE");
        newUser.setCreatedAt(LocalDateTime.now());
        newUser.setUpdatedAt(LocalDateTime.now());
        
        // 保存用户到数据库
        int result = userMapper.insert(newUser);
        if (result <= 0) {
            throw new RuntimeException("用户注册失败");
        }
        
        // 生成token - 修正参数顺序
        String accessToken = jwtUtil.generateAccessToken(newUser.getUsername(), newUser.getUserId(), newUser.getUserType());
        String refreshToken = jwtUtil.generateRefreshToken(newUser.getUsername(), newUser.getUserId());
        
        // 将refresh token存储到Redis
        String refreshTokenKey = "refresh_token:" + newUser.getUserId();
        redisTemplate.opsForValue().set(refreshTokenKey, refreshToken, 7, TimeUnit.DAYS);
        
        return new LoginResponse(accessToken, refreshToken, newUser.getUserType(), newUser.getRealName(), 86400000L);
    }
}